/**
 * @BitmapMovie.as
 *
 * @author sodaChen mail:asframe@qq.com
 * @version 1.0
 * <br>Copyright (C), 2012 ASFrame.com
 * <br>This program is protected by copyright laws.
 * <br>Program Name:ASFrame
 * <br>Date:2013-6-19
 */
package com.asframe.display.bmp
{
	import com.asframe.display.data.FrameData;
	import com.asframe.display.data.MovieData;
	import com.asframe.events.BitmapMovieEvent;
	import com.asframe.lang.IDestory;
	import com.asframe.mgr.AnimMrg;
	import com.asframe.tick.ITick;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;

	/**
	 * 位图序列帧播放器，利用Bitmap实现的动画.这里是纯粹的一帧帧播放。不做其他的任何处理。
	 * @author sodaChen
	 * #Date:2013-6-19
	 */
	public class BitmapPlayer extends Sprite implements ITick,IDestory
	{
		/** 是否自动更新属性，默认是自动更新 **/
		public var autoUpdate			:Boolean = true;
		/** 显示位图对象 **/
		public var bitmap				:Bitmap;
		/** 附加的额外数据 **/
		public var extra				:*;
		/** 动画播放帧频(播放速度，单位是毫秒) **/
		public var frameRate			:int = 33;
		/** 当前动画是否循环播放 **/
		public var isLoop				:Boolean;
		/** 是否正在播放 **/
		public var isPlaying			:Boolean;
		/** 播放结束的回调函数 **/
		public var playComplete			:Function;
		/** 帧回调函数 **/
		public var frameCallBack		:Function;

		/** 开始播放的帧数(0开始) **/
		protected var mStart			:int;
		/** 播放的帧数 **/
		protected var mEnd				:int;
		/** 最大帧数 **/
		protected var mTotalFrame		:int;
		/** 当前帧数 **/
		protected var mCurrentFrame	:int;
		/** 当前播放动画的图像数组数据 **/
		protected var mBitmapDatas		:Vector.<BitmapData>;
		/** 当前播放动画的帧数组数据 **/
		protected var mFrames			:Vector.<FrameData>;
		/** 帧数据 **/
		protected var mFrameData		:FrameData;
		protected var isPlayOver		:Boolean;
		/** 当前播放的动画数据 **/
		protected var movieData		:MovieData;

		public function BitmapPlayer()
		{
			bitmap = new Bitmap();
			addChild(bitmap);
		}
		/**
		 * 渲染当前帧数的图像信息
		 */
		public function render():void
		{
			bitmap.bitmapData = mBitmapDatas[mCurrentFrame];
			//更新位置
			if(mFrames != null)
			{
				mFrameData = mFrames[mCurrentFrame];
				bitmap.x = mFrameData.x;
				bitmap.y = mFrameData.y;
				//这里主要是TexturePacker的Plist数据
				bitmap.rotation = 0;
				if(mFrameData.rotation != 0)
				{
					bitmap.rotation = mFrameData.rotation;
				}
			}
			if(frameCallBack != null)
				frameCallBack(this);
		}
		/**
		 * 获取到当前帧的帧数据结构(只读)
		 * @return
		 *
		 */
		public function get currentFrameData():FrameData
		{
			return mFrames[mCurrentFrame];
		}
		/**
		 * 获取动画的当前帧(只读)
		 * @return
		 */
		public function get currentFrame():int
		{
			return mCurrentFrame + 1;
		}
		/**
		 * 返回动画的最大帧数(只读)
		 * @return
		 */
		public function get totalFrame():int
		{
			return mTotalFrame;
		}
		/**
		 * 设置动画数据
		 * @param movieData 包含图片动画的数据结构
		 *
		 */
		public function setMovieData(movieData:MovieData):void
		{
			this.movieData = movieData;
			this.mFrames = movieData.frameDatas;
			this.mBitmapDatas = movieData.bitmapDatas;
			mCurrentFrame = 0;
			mStart = 0;
			mEnd = movieData.bitmapDatas.length;
			render();
		}
		/**
		 * 播放Bitmap动画
		 * @param isLoop 是否循环播放，为true时不能具备callBack函数
		 * @param callBack 结束帧数时的回调函数，注意这个有参数时isLoop必须为false
		 */
		public function play(isLoop:Boolean = true,playComplete:Function = null):void
		{
			if(isLoop && playComplete != null)
				throw new Error("不能循环的时候具备playComplete参数");

			if(playComplete != null)
			{
				this.playComplete = playComplete;
			}
			this.isLoop = isLoop;
			//还没播放
			if(!isPlaying)
			{
				isPlaying = true;
				if(autoUpdate)
					AnimMrg.getInstance().addAnim(this);
			}
			render();
		}
		/**
		 * 停止播放动画
		 */
		public function stop():void
		{
			if(isPlaying)
			{
				AnimMrg.getInstance().addAnim(this);
				isPlaying = false;
			}
		}
		/**
		 * 跳转到指定的帧数，并且播放动画
		 * @param start 需要跳转的帧数
		 * @param end 结束帧数，默认是动画的最后一帧
		 * @param isLoop 是否循环
		 * @param playComplete 播放完一次的回调函数
		 *
		 */
		public function gotoAndPlay(start:int, end:int = -1,isLoop:Boolean = true,playComplete:Function = null):void
		{
			if(isLoop && playComplete != null)
				throw new Error("不能循环的时候具备playComplete参数");

			this.mStart = start - 1;
			this.mCurrentFrame = mStart;
			if(end != -1)
				this.mEnd = end;

			play(isLoop,playComplete);
		}
		public function gotoAndStop(stopFrame:int = -1):void
		{
			stop();
			//渲染当前帧
			if(stopFrame == -1)
				mCurrentFrame = mEnd - 1;
			else
				mCurrentFrame = stopFrame - 1;

			render();
		}
		public function tick():void
		{
			//不处于播放状态
			if(!isPlaying)
			{
				return ;
			}
			mCurrentFrame++;
			if(mCurrentFrame < mEnd)
			{
				//这里可以为了提升性能，去掉方法，直接写代码。主要是因为调用频繁
				render();
				return ;
			}
			if(isLoop)
			{
				mCurrentFrame = mStart;
				render();
				return ;
			}
			framePlayOver();
		}
		/**
		 * 帧播放结束
		 */
		protected function framePlayOver():void
		{
			//回调
			if(playComplete != null || hasEventListener(BitmapMovieEvent.PLAY_OVER))
			{
				//这里设置属性，是防止回调函数里有再次调用play方法
				isPlayOver = true;
				if(hasEventListener(BitmapMovieEvent.PLAY_OVER))
					dispatchEvent(new BitmapMovieEvent(BitmapMovieEvent.PLAY_OVER));
				//这里这样设计的原因，是有可能playComplete回调的时候，还会再次调用play之类的方法进行重新设置playComplete
				if(playComplete != null)
				{
					var temp:Function = playComplete;
					playComplete = null;
					if(temp.length == 1)
						temp(this);
					else
						temp();
				}
				if(isPlayOver)
					stop();
			}
			else
			{
				//没有循环，则表示已经播放完了
				stop();
			}
		}
		public function destroy(o:* = null):void
		{

		}
	}
}


